#ifndef SC_DEMUXER_H
#define SC_DEMUXER_H

#include "common.h"

#include <stdbool.h>
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>

#include "trait/packet_source.h"
#include "trait/packet_sink.h"
#include "util/net.h"
#include "util/thread.h"

/* 
muxer是合并将视频文件、音频文件和字幕文件合并为某一个视频格式。
    如，可将a.avi, a.mp3, a.srt用muxer合并为mkv格式的视频文件。
demuxer是拆分这些文件的。

自定义视频解封装（复用）Demux上下文 。
*/
struct sc_demuxer {
    struct sc_packet_source packet_source; // packet source trait

    const char *name; // must be statically allocated (e.g. a string literal)

    // 已经初始化成功的视频socket：server->video_socket
    sc_socket socket;
    sc_thread thread;

    // 回调事件
    const struct sc_demuxer_callbacks *cbs;
    // 回调数据    
    void *cbs_userdata;
};

enum sc_demuxer_status {
    SC_DEMUXER_STATUS_EOS,
    SC_DEMUXER_STATUS_DISABLED,
    SC_DEMUXER_STATUS_ERROR,
};

// 定义回调事件的签名
struct sc_demuxer_callbacks {
    /*
    视频流关闭事件
    @param demuxer
    @param userdata
    */    
    void (*on_ended)(struct sc_demuxer *demuxer, enum sc_demuxer_status,
                     void *userdata);
};

/* 
初始化自定义视频解封装器。第一步
@param demuxer 解复用上下文
@param name The name must be statically allocated (e.g. a string literal)
@param socket 提前已经连接成功的视频socket
@param cbs 回调事件
@param cbs_userdata 回调事件的用户数据，目前全传NULL
*/
void
sc_demuxer_init(struct sc_demuxer *demuxer, const char *name, sc_socket socket,
                const struct sc_demuxer_callbacks *cbs, void *cbs_userdata);

/* 
开启一个异步线程进行视频解封装，第三步
@param demuxer 解复用上下文
@return 开启成功返回true,否则返回false
*/
bool
sc_demuxer_start(struct sc_demuxer *demuxer);

/*
等待视频流解封装线程结束（本方法执行完成才执行下一步），第四步
@param demuxer 解复用上下文
*/
void
sc_demuxer_join(struct sc_demuxer *demuxer);

#endif
